30. Decorator 您所在的位置:网站首页 js 类的写法 30. Decorator

30. Decorator

2024-07-02 17:20| 来源: 网络整理| 查看: 265

方法的装饰方法的装饰

装饰器不仅可以装饰类,还可以装饰类的属性。

class Person { @readonly name() { return `${this.first} ${this.last}` }}

上面代码中,装饰器readonly用来装饰“类”的name方法。

装饰器函数readonly一共可以接受三个参数。

function readonly(target, name, descriptor){ // descriptor对象原来的值如下 // { // value: specifiedFunction, // enumerable: false, // configurable: true, // writable: true // }; descriptor.writable = false; return descriptor;}readonly(Person.prototype, 'name', descriptor);// 类似于Object.defineProperty(Person.prototype, 'name', descriptor);

装饰器第一个参数是类的原型对象,上例是Person.prototype,装饰器的本意是要“装饰”类的实例,但是这个时候实例还没生成,所以只能去装饰原型(这不同于类的装饰,那种情况时target参数指的是类本身);第二个参数是所要装饰的属性名,第三个参数是该属性的描述对象。

另外,上面代码说明,装饰器(readonly)会修改属性的描述对象(descriptor),然后被修改的描述对象再用来定义属性。

下面是另一个例子,修改属性描述对象的enumerable属性,使得该属性不可遍历。

class Person { @nonenumerable get kidCount() { return this.children.length; }}function nonenumerable(target, name, descriptor) { descriptor.enumerable = false; return descriptor;}

下面的@log装饰器,可以起到输出日志的作用。

class Math { @log add(a, b) { return a + b; }}function log(target, name, descriptor) { var oldValue = descriptor.value; descriptor.value = function() { console.log(`Calling ${name} with`, arguments); return oldValue.apply(this, arguments); }; return descriptor;}const math = new Math();// passed parameters should get logged nowmath.add(2, 4);

上面代码中,@log装饰器的作用就是在执行原始的操作之前,执行一次console.log,从而达到输出日志的目的。

装饰器有注释的作用。

@testableclass Person { @readonly @nonenumerable name() { return `${this.first} ${this.last}` }}

从上面代码中,我们一眼就能看出,Person类是可测试的,而name方法是只读和不可枚举的。

下面是使用 Decorator 写法的组件,看上去一目了然。

@Component({ tag: 'my-component', styleUrl: 'my-component.scss'})export class MyComponent { @Prop() first: string; @Prop() last: string; @State() isVisible: boolean = true; render() { return ( Hello, my name is {this.first} {this.last} ); }}

如果同一个方法有多个装饰器,会像剥洋葱一样,先从外到内进入,然后由内向外执行。

function dec(id){ console.log('evaluated', id); return (target, property, descriptor) => console.log('executed', id);}class Example { @dec(1) @dec(2) method(){}}// evaluated 1// evaluated 2// executed 2// executed 1

上面代码中,外层装饰器@dec(1)先进入,但是内层装饰器@dec(2)先执行。

除了注释,装饰器还能用来类型检查。所以,对于类来说,这项功能相当有用。从长期来看,它将是 JavaScript 代码静态分析的重要工具。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有